package benchmark.energy;


//静态属性
import benchmark.energy.tx.ImportStaticDataTx;
import benchmark.energy.tx.ImportTemporalDataTx;
import benchmark.energy.tx.ImportTemporalDataTx.EnergyStatus;
import com.google.common.collect.AbstractIterator;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.*;

public class EnergyDataTxGenerator {
    public static final String[] properties = "load_signal,solar_cosmo_p,solar_cosmo_u,solar_ecmwf_p,solar_ecmwf_u,wind_cosmo_p,wind_cosmo_u,wind_ecmwf_p,wind_ecmwf_u".split(",");
    private final File dir;
    private final List<EnergyStatusCsvReader> propIters = new LinkedList<>();
    public EnergyDataTxGenerator(File dataRoot) throws IOException {
        this.dir = dataRoot;
        for(String p : properties){
            propIters.add(new EnergyStatusCsvReader(new File(dir, p+".csv")));
        }
    }

    public ImportStaticDataTx readNetwork() throws IOException {
        List<ImportStaticDataTx.EnergyNode> nodes = new ArrayList<>();
        try(BufferedReader reader = new BufferedReader(new FileReader(new File(dir, "network_nodes.csv")))){
            reader.readLine();
            String line;
            while((line = reader.readLine())!=null){
                String[] arr = line.split(",");
                ImportStaticDataTx.EnergyNode node = new ImportStaticDataTx.EnergyNode();
                node.setRawId(Integer.parseInt(arr[0]));
                node.setName(arr[1]);
                node.setCountry(arr[2]);
                node.setVoltage(Integer.parseInt(arr[3]));
                node.setLatitude(Float.parseFloat(arr[4]));
                node.setLongitude(Float.parseFloat(arr[5]));
                nodes.add(node);
            }
        }
        List<ImportStaticDataTx.EnergyRel> rels = new ArrayList<>();
        try(BufferedReader reader = new BufferedReader(new FileReader(new File(dir, "network_edges.csv")))){
            reader.readLine();//skip header
            String line;
            while((line = reader.readLine())!=null){
                String[] arr = line.split(",");
                ImportStaticDataTx.EnergyRel rel = new ImportStaticDataTx.EnergyRel();
                rel.setFromRawId(Integer.parseInt(arr[0]));
                rel.setToRawId(Integer.parseInt(arr[1]));
                rel.setX(Float.parseFloat(arr[2]));
                rel.setY(Float.parseFloat(arr[3]));
                rel.setLimit(Integer.parseInt(arr[4]));
                rel.setLength(Float.parseFloat(arr[5]));
                rels.add(rel);
            }
        }
        return new ImportStaticDataTx(nodes, rels);
    }

    public Iterator<ImportTemporalDataTx> readTemporalStatus(int linePerTx) throws IOException {
        return new TxWrapper();
    }

    public void close() throws IOException {
        for(EnergyStatusCsvReader r:propIters){
            r.close();
        }
    }

    private class TxWrapper extends AbstractIterator<ImportTemporalDataTx> {
        @Override
        protected ImportTemporalDataTx computeNext() {
            Map<Integer, List<Float>> values = new HashMap<>();
            final int[] time = new int[]{-1};
            propIters.forEach(reader -> {
                ImportTemporalDataTx.MultiEntityEnergyStatus content = reader.next();
                if(time[0]==-1) time[0] = content.getTimePoint();
                else assert time[0]==content.getTimePoint();
                content.getStatus().forEach((nodeId, val) -> {
                    values.putIfAbsent(nodeId, new ArrayList<>());
                    List<Float> lst = values.get(nodeId);
                    lst.add(val);
                });
            });
            List<EnergyStatus> result = new ArrayList<>();
            values.forEach((nodeId, propVals) -> {
                EnergyStatus s = new EnergyStatus();
                s.setTimePoint(time[0]);
                s.setNodeId(nodeId);
                s.setStatus(propVals);
                result.add(s);
            });
            return new ImportTemporalDataTx(result);
        }
    }
}


//
//    ArrayList<String[]> load_signal = Helper.csvReader("PATH");//本地需求
//    ArrayList<String[]> solar_cosmo_p = Helper.csvReader("PATH");//太阳能在 COSMO 下 Proportional(比例) 产能布局下的信号
//    ArrayList<String[]> solar_cosmo_u = Helper.csvReader("PATH");//太阳能在 COSMO 下 Uniform(统一) 产能布局下的信号
//    ArrayList<String[]> solar_ecmwf_p = Helper.csvReader("PATH");//太阳能在 ECMWF 下 Proportional(比例) 产能布局下的信号
//    ArrayList<String[]> solar_ecmwf_u = Helper.csvReader("PATH");//太阳能在 ECMWF 下 Uniform(统一) 产能布局下的信号
//    ArrayList<String[]> wind_cosmo_p = Helper.csvReader("PATH");//风能在 COSMO 下 Proportional(比例) 产能布局下的信号
//    ArrayList<String[]> wind_cosmo_u = Helper.csvReader("PATH");//风能在 COSMO 下 Uniform(统一) 产能布局下的信号
//    ArrayList<String[]> wind_ecmwf_p = Helper.csvReader("PATH");//风能在 ECMWF 下 Proportional(比例) 产能布局下的信号
//    ArrayList<String[]> wind_ecmwf_u = Helper.csvReader("PATH");//风能在 ECMWF 下 Uniform(统一) 产能布局下的信号
//    ArrayList<String[]> nodeStaticDataList = Helper.csvReader("PATH");
//
//    int col = load_signal.get(0).length - 1;
//    int row = load_signal.size();
//
//        for (int i = 0; i<row; i++){
//        for (int j = 0; j<col-1; j++){
//        int ID = Integer.parseInt(nodeStaticDataList.get(j)[0]);
//        String nowTime = load_signal.get(j)[0];
//        float load_signal = Float.parseFloat(load_signal.get(i)[j+1]);
//        float solar_cosmo_p = Float.parseFloat(solar_cosmo_p.get(i)[j+1]);
//        float solar_cosmo_u = Float.parseFloat(solar_cosmo_u.get(i)[j+1]);
//        float solar_ecmwf_p = Float.parseFloat(solar_ecmwf_p.get(i)[j+1]);
//        float solar_ecmwf_u = Float.parseFloat(solar_ecmwf_u.get(i)[j+1]);
//        float wind_cosmo_p = Float.parseFloat(wind_cosmo_p.get(i)[j+1]);
//        float wind_cosmo_u = Float.parseFloat(wind_cosmo_u.get(i)[j+1]);
//        float wind_ecmwf_p = Float.parseFloat(wind_ecmwf_p.get(i)[j+1]);
//        float wind_ecmwf_u = Float.parseFloat(wind_ecmwf_u.get(i)[j+1]);
//        }
//        }
//public class WriteStaticData {
//    @Test
//    public static void  writeStaticData(){
//        ArrayList<String[]> nodeStaticDataList = new ArrayList<>();
//
//        nodeStaticDataList = Helper.csvReader("PATH");
//
//
//        int nLength = nodeStaticDataList.size();
//        for (int i = 0; i<nLength; i++){
//            int ID = Integer.parseInt(nodeStaticDataList.get(i)[0]);
//            String name = nodeStaticDataList.get(i)[1];
//            String country = nodeStaticDataList.get(i)[2];
//            int voltage = Integer.parseInt(nodeStaticDataList.get(i)[3]);
//            float latitude = Float.parseFloat(nodeStaticDataList.get(i)[4]);
//            float longitude = Float.parseFloat(nodeStaticDataList.get(i)[5]);
////以上组成一个节点的静态属性，按条写入就可以
//        }
//        //边属性
//        ArrayList<String[]> edgeStaticDataList =new ArrayList<>();
//        edgeStaticDataList = Helper.csvReader("PATH");
//        int eLength = edgeStaticDataList.size();
//        for (int i = 0; i<eLength; i++){
//            int fromNode = Integer.parseInt(edgeStaticDataList.get(i)[0]);
//            int toNode = Integer.parseInt(edgeStaticDataList.get(i)[1]);
//            String edge = edgeStaticDataList.get(i)[0]+"_"+edgeStaticDataList.get(i)[1];        //多生成了一个edge属性
//            float X = Float.parseFloat(edgeStaticDataList.get(i)[2]);
//            float Y = Float.parseFloat(edgeStaticDataList.get(i)[3]);
//            int limit = Integer.parseInt(edgeStaticDataList.get(i)[4]);
//            float length = Float.parseFloat(edgeStaticDataList.get(i)[5]);
////边的静态属性，按条写入
//        }
//    }
//
//}
//
////help.er csvReader
//import com.csvreader.CsvReader;
//
//        import java.nio.charset.Charset;
//        import java.util.ArrayList;
//
//public class Helper {
//    public static ArrayList<String[]> csvReader(String filePath){
//        ArrayList<String[]> csvList = new ArrayList<String[]>();
//        try{
//            CsvReader reader =new CsvReader(filePath,',', Charset.forName("GBK"));
//            reader.readHeaders();
//            while (reader.readRecord()){
//                csvList.add(reader.getValues());
//            }
//            reader.close();
//        }catch (Exception e){
//            e.printStackTrace();
//        }
//        return csvList;
//    }
//}


